Skip to content

Fix integer overflow in section and subsection size checks#2694

Merged
sbc100 merged 1 commit intoWebAssembly:mainfrom
sumleo:fix/binary-reader-size-overflow
Feb 13, 2026
Merged

Fix integer overflow in section and subsection size checks#2694
sbc100 merged 1 commit intoWebAssembly:mainfrom
sumleo:fix/binary-reader-size-overflow

Conversation

@sumleo
Copy link
Contributor

@sumleo sumleo commented Feb 12, 2026

Summary

  • Multiple places in the binary reader computed boundary offsets by adding a size value to the current position before checking bounds (e.g. read_end_ = state_.offset + section_size). On platforms where size_t is 32-bit, large size values cause the addition to wrap around, producing a small result that incorrectly passes subsequent bounds checks.
  • Replace all addition-based checks with subtraction-based equivalents (size > end - offset), which are safe because the invariant state_.offset <= read_end_ is always maintained.
  • Add regression tests with oversized section and subsection sizes.

Details

The vulnerable pattern appears in 6 locations:

Function Line Expression
ReadSections 3109 read_end_ = state_.offset + section_size
ReadNameSection 2036 subsection_end = state_.offset + subsection_size
ReadDylinkSection 2227 subsection_end = state_.offset + subsection_size
ReadLinkingSection 2359 subsection_end = state_.offset + subsection_size
ReadStr 420 state_.offset + str_len <= read_end_
ReadBytesWithSize 445 state_.offset + size <= read_end_

On 32-bit platforms where Offset is size_t (= uint32_t), a section_size of e.g. 0xFFFFFFF0 added to an offset of 0x20 produces 0x10, which passes the check read_end_ <= state_.size even though the section extends far past the buffer.

Fix: Use subtraction from the known-good bound instead:

// Before (overflow-prone):
ERROR_UNLESS(state_.offset + size <= read_end_, ...);
// After (overflow-safe):
ERROR_UNLESS(size <= read_end_ - state_.offset, ...);

For ReadSections, add an explicit overflow check before computing read_end_.

Test plan

  • New test BinaryReader.OversizedSectionSize with a 2 GiB section size in a tiny module
  • New test BinaryReader.OversizedSubsectionSize with a name section subsection exceeding the section boundary
  • All existing unit tests pass (129 tests)

@sumleo sumleo force-pushed the fix/binary-reader-size-overflow branch from e4704eb to 8ebb9a4 Compare February 12, 2026 08:40
Copy link
Member

@sbc100 sbc100 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

As with the other new tests, I wonder if we should have a TODO to move these tests upstream?

@sumleo sumleo force-pushed the fix/binary-reader-size-overflow branch from 8ebb9a4 to 52f9592 Compare February 12, 2026 23:54
@sumleo
Copy link
Contributor Author

sumleo commented Feb 12, 2026

Done, added TODO comments to both tests to move them upstream into the spec repo.

@sbc100 sbc100 enabled auto-merge (squash) February 12, 2026 23:55
Multiple places in the binary reader computed boundary offsets by
adding a size value to the current position before checking bounds:

  read_end_ = state_.offset + section_size;
  subsection_end = state_.offset + subsection_size;
  state_.offset + str_len <= read_end_
  state_.offset + size <= read_end_

On platforms where size_t is 32-bit, a large size value can cause the
addition to wrap around, producing a small result that incorrectly
passes subsequent bounds checks.

Replace all addition-based checks with subtraction-based equivalents
(e.g. `size > read_end_ - state_.offset`), which are safe because the
invariant state_.offset <= read_end_ is always maintained.

Affected functions:
  - ReadSections (section size)
  - ReadNameSection (subsection size)
  - ReadDylinkSection (subsection size)
  - ReadLinkingSection (subsection size)
  - ReadStr (string length)
  - ReadBytesWithSize (data size)

Add regression tests with oversized section and subsection sizes.
auto-merge was automatically disabled February 13, 2026 14:35

Head branch was pushed to by a user without write access

@sumleo sumleo force-pushed the fix/binary-reader-size-overflow branch from 52f9592 to 529663b Compare February 13, 2026 14:35
@sbc100 sbc100 merged commit 6ca912c into WebAssembly:main Feb 13, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants